#include "llt.h"

#include <stdio.h>

#include <k_task.h>

static int task_exc_div_0(uintptr_t arg)
{
    int div = 0;
    int exc = 1 / div;
    printf("exc is %d\n", exc);

    return 0;
}

static int task_exc_svc(uintptr_t arg)
{
    __asm__ __volatile__("svc 0x00");

    return 0;
}

static int task_exc_invalid_addr(uintptr_t arg)
{
    *((volatile uint32_t *)0x0) = 0;

    return 0;
}

static int task_exc_stack_overflow(uintptr_t arg)
{
    char a[0x100] = {0};

    printf("a addr %p\n", a);

    return 0;
}

void test_task_exception_demo(void **state)
{
    task_spawn("exc_div_0", 30, 0, 0x100, task_exc_div_0, 0);
    task_spawn("exc_svc", 30, 0, 0x100, task_exc_svc, 0);
    task_spawn("exc_invalid_addr", 30, 0, 0x100, task_exc_invalid_addr, 0);
    task_spawn("exc_stack_overflow", 30, 0, 0x100, task_exc_stack_overflow, 0);
}

/** test entry */

void test_exception(struct tester_case *caser)
{
    UnitTest tests[] = {
        unit_test(test_task_exception_demo),
    };

    caser->stats->totals = sizeof(tests) / sizeof(tests[0]);
    caser->stats->fails = run_tests(tests);
}

TESTER_CASE_DEF("test_exception", test_exception, NULL, NULL, 0);
